'use client';

import { clientQueryPostDetails, postView } from '@/services/api';
import { toRelativeTime } from '@/lib/tool';
import type { IPostClientDetails, IPostComment } from '@/interfaces';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useInfiniteQuery, useMutation } from '@tanstack/react-query';
import useToast from '@/hooks/useToast';
import Content from '@/app/[locale]/posts/[id]/content';
import Comment from '@/app/[locale]/posts/[id]/comment';
import PostComment from '@/app/[locale]/posts/[id]/postComment';
import PostName from '@/app/[locale]/common/post/name';
import type { IPostIdPageContext } from '@/contexts/post-id';
import { PostIdPageContext } from '@/contexts/post-id';
import PcBox from '@/app/[locale]/common/other/pc';
import Spinner from '@/app/[locale]/component/spinner/spinner';
import PostIdH5Page from '@/app/[locale]/posts/[id]/h5';

export default function PostIdPage({
  source,
  translatedFields,
}: IPostIdPageContext) {
  const viewRef = useRef(false);
  const { show } = useToast();
  const [pages, setPages] = useState<IPostComment[]>(
    source.postDetails.data.content,
  );
  const queryKey = [
    '/forum',
    '/posts',
    '/client',
    source.postDetails.basic.id,
    '/details',
    'infinite',
  ];

  const postViewMutation = useMutation(postView);

  const clientQueryPostDetailsQuery = useInfiniteQuery(
    queryKey,
    async (context) => {
      return (await clientQueryPostDetails({
        id: context.queryKey[3],
        query: context.pageParam,
      })) as IPostClientDetails;
    },
    {
      keepPreviousData: true,
      getPreviousPageParam: (firstPage) => {
        if (!firstPage.data!.pageable.previous) {
          return;
        }
        return {
          page: Math.max(firstPage.data!.pageable.page - 1, 0),
        };
      },
      getNextPageParam: (lastPage) => {
        if (!lastPage.data!.pageable.next) {
          return;
        }
        return {
          page: Math.min(
            lastPage.data!.pageable.page + 1,
            lastPage.data!.pageable.pages,
          ),
        };
      },
      initialData: () => {
        return {
          pages: [source.postDetails],
          pageParams: [{ page: 0 }],
        };
      },
    },
  );

  const postViewCallback = useCallback(() => {
    const id = source.postDetails.basic.id;
    if (!viewRef.current) {
      viewRef.current = true;
      postViewMutation.mutateAsync({
        id,
      });
    }
  }, [postViewMutation, source.postDetails.basic.id]);

  useEffect(() => {
    postViewCallback();
  }, [postViewCallback]);
  useEffect(() => {
    function handleContent(item: IPostComment) {
      item.comment._createdOnText = toRelativeTime(item.comment.createdOn);
      item.content.forEach((value) => {
        value.reply._createdOnText = toRelativeTime(value.reply.createdOn);
        value.content.forEach((value1) => {
          value1.reply._createdOnText = toRelativeTime(value1.reply.createdOn);
          value1.content.forEach((value2) => {
            value2.reply._createdOnText = toRelativeTime(
              value2.reply.createdOn,
            );
          });
        });
      });
      return item;
    }

    if (clientQueryPostDetailsQuery.data) {
      setPages(
        clientQueryPostDetailsQuery.data.pages
          .flatMap((item) => {
            item.basic._contentUpdatedOnText = toRelativeTime(
              item.basic.contentUpdatedOn,
            );
            return item.data.content;
          })
          .map(handleContent),
      );
    }
  }, [clientQueryPostDetailsQuery.data]);

  async function onClickLoadMore() {
    try {
      await clientQueryPostDetailsQuery.fetchNextPage();
    } catch (e) {
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  return (
    <PostIdPageContext.Provider value={{ source, translatedFields, queryKey }}>
      <PcBox classs="col px-2 py-4">
        <div className="row mx-0">
          <div className="col px-0">
            <div className="card border-0">
              <div className="card-body">
                <PostName
                  item={source.postDetails.basic}
                  isEdit={
                    source.path.user?.id === source.postDetails.basic.createdBy
                  }
                  isJustifyContentCenter
                  boxClassName="h4 mb-0 py-5"
                  textDecorationNone
                  isPostReviewHistory
                  translatedFields={translatedFields.reviewHistory}
                />
              </div>
            </div>
          </div>
        </div>

        <Content />

        {pages.map((item, index) => {
          return (
            <Comment
              key={item.comment.id}
              commentItem={item}
              commentIndex={index}
            />
          );
        })}

        {clientQueryPostDetailsQuery.hasNextPage && (
          <LoadMoreCommentBtn
            isLoading={clientQueryPostDetailsQuery.isLoading}
            onClickLoadMore={onClickLoadMore}
          />
        )}

        <PostComment />
      </PcBox>

      <PostIdH5Page />
    </PostIdPageContext.Provider>
  );
}

const LoadMoreCommentBtn = ({
  onClickLoadMore,
  isLoading,
}: {
  onClickLoadMore: () => void;
  isLoading: boolean;
}) => {
  return (
    <div className="row mx-0">
      <div className="col px-0">
        <div className="card border-0">
          <div className="card-body">
            <button
              onClick={onClickLoadMore}
              disabled={isLoading}
              type="button"
              className="btn rounded-pill text-secondary-emphasis w-100"
            >
              {isLoading ? <Spinner /> : <i className="bi bi-three-dots"></i>}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};
